import 'package:equatable/equatable.dart';

import '../../../util/data_type.dart';
import 'user_state.dart';

class RoomInfo extends Equatable {
  final String? type;
  final String? code;
  final String? createDate;
  final String? updateDate;
  int severalInning = 1;
  int status = 0;
  final Rule? rule;
  final GameInfo gameInfo;

  bool checkExistsRule(String ruleParam) {
    return rule?.checkExistsRule(ruleParam) ?? false;
  }

  factory RoomInfo.empty() =>
      RoomInfo(gameInfo: GameInfo(status: 1, version: 0));

  RoomInfo copyWith(RoomInfo newState) {
    return RoomInfo(
        code: newState.code,
        type: newState.type,
        rule: newState.rule,
        severalInning: severalInning,
        gameInfo: newState.gameInfo);
  }

  RoomInfo(
      {this.code,
      this.createDate,
      this.updateDate,
      this.type,
      this.rule,
      this.severalInning = 0,
      required this.gameInfo,
      this.status = 0});

  factory RoomInfo.formJSON(json) {
    if (json == null || json is! Map<String, dynamic>) {
      return RoomInfo(gameInfo: GameInfo());
    }
    var rule = Rule.formJSON(json["rule"]);
    var gameInfo = GameInfo.formJSON(json["gameInfo"]);
    return RoomInfo(
        code: asT<String>(json["code"]),
        status: asT<int>(json["status"]) ?? 0,
        type: asT<String>(json["type"]),
        severalInning: asT<int>(json["severalInning"]) ?? 1,
        rule: rule,
        gameInfo: gameInfo);
  }

  @override
  List<Object?> get props => [gameInfo.residue];

  int getUserCount() {
    return rule?.userCount ?? 2;
  }
}

class Rule {
  int userCount;
  int? numberGame;
  int? turns;
  int? type;
  List<String>? rules;
  String? ruleStr;
  String? roomType;
  String? roomTypeStr;

  bool checkExistsRule(String rule) {
    return rules?.contains(rule) ?? false;
  }

  Rule(
      {this.userCount = 0,
      this.numberGame,
      this.turns,
      this.type,
      this.rules,
      this.ruleStr,
      this.roomType,
      this.roomTypeStr});

  factory Rule.formJSON(Map<String, dynamic>? json) {
    if (json == null) {
      return Rule();
    }
    List? rulesJson = json["rules"];
    List<String> ruleList = [];
    if (rulesJson != null) {
      for (var element in rulesJson) {
        ruleList.add(element.toString());
      }
    }
    return Rule(
        userCount: asT<int>(json["userCount"]) ?? 0,
        numberGame: asT<int>(json["numberGame"]),
        turns: asT<int>(json["turns"]),
        type: asT<int>(json["type"]),
        ruleStr: asT<String>(json["ruleStr"]),
        roomType: asT<String>(json["roomType"]),
        roomTypeStr: asT<String>(json["roomTypeStr"]),
        rules: ruleList);
  }
}

class GameInfo {
  int? id;
  String? name;
  String? code;
  int? roomId;
  int version;
  int synVersion;
  int status;
  int residue;
  int cardCount = 108;
  int exportUserId;
  int exportCard;
  List<UserState>? otherUsers;
  List<UserState>? allUser;
  UserState? currentUser;

  GameInfo(
      {this.currentUser,
      this.otherUsers,
      this.name,
      this.residue = 0,
      this.status = 1,
      this.cardCount = 108,
      this.exportUserId = 0,
      this.version = 0,
      this.exportCard = 1,
      this.synVersion = 0,
      this.allUser,
      this.code});

  factory GameInfo.formJSON(json) {
    if (json == null || json is! Map<String, dynamic>) {
      return GameInfo();
    }
    List? otherUsersJson = json["otherUsers"];
    List<UserState> otherUsers = [];
    if (otherUsersJson != null) {
      otherUsersJson.forEach((element) {
        UserState info = UserState.fromJson(element);
        otherUsers.add(info);
      });
    }

    List? allUserJson = json["allUser"];
    List<UserState> allUser = [];
    if (allUserJson != null) {
      for (var element in allUserJson) {
        UserState info = UserState.fromJson(element);
        allUser.add(info);
      }
    }

    return GameInfo(
        otherUsers: otherUsers,
        allUser: allUser,
        name: asT<String>(json["name"]) ?? "??????",
        code: asT<String>(json["code"]) ?? "??????",
        residue: asT<int>(json["residue"]) ?? 0,
        status: asT<int>(json["status"]) ?? 1,
        exportUserId: asT<int>(json["exportUserId"]) ?? 1,
        cardCount: asT<int>(json["cardCount"]) ?? 108,
        exportCard: asT<int>(json["exportCard"]) ?? 1,
        version: asT<int>(json["version"]) ?? 0,
        synVersion: asT<int>(json["synVersion"]) ?? 0,
        currentUser: UserState.fromJson(json["currentUser"]));
  }
}
